package com.gzc.just.play.last.war.sceneserver.gameobject.base;

import java.io.Serializable;
import java.util.UUID;

/**
 * 游戏对象基类 - 所有游戏对象的基础类
 * 
 * 对应C++ SSGameObject
 * 
 * @author AI Assistant
 * @version 1.0.0
 * @since 2025-11-22
 */
public abstract class GameObject implements Serializable {
    private static final long serialVersionUID = 1L;

    // 基础属性
    private long objectId;              // 对象唯一ID
    private String objectUUID;          // 对象UUID
    private GameObjectType objectType;  // 对象类型
    private GameObjectCamp camp;        // 所属阵营
    private long masterGuid;            // 主人GUID（如宠物的主人）
    
    // 位置信息
    private double posX;                // X坐标
    private double posY;                // Y坐标
    private double posZ;                // Z坐标
    
    // 方向
    private float directionX;           // 方向向量X
    private float directionY;           // 方向向量Y
    private float directionZ;           // 方向向量Z
    
    // 生命周期
    private boolean active;             // 是否激活
    private boolean destroyed;          // 是否销毁
    private long createTime;            // 创建时间
    private long lastUpdateTime;        // 最后更新时间
    
    // 可见性
    private boolean visible;            // 是否可见
    private long visibilityRange;       // 可见范围

    /**
     * 构造函数
     */
    public GameObject(long objectId, GameObjectType objectType, GameObjectCamp camp) {
        this.objectId = objectId;
        this.objectUUID = UUID.randomUUID().toString();
        this.objectType = objectType;
        this.camp = camp;
        this.active = false;
        this.destroyed = false;
        this.visible = true;
        this.createTime = System.currentTimeMillis();
        this.lastUpdateTime = this.createTime;
        this.masterGuid = 0;
        this.visibilityRange = 1000;
    }

    // Getter和Setter方法
    public long getObjectId() {
        return objectId;
    }
    
    public void setObjectId(long objectId) {
        this.objectId = objectId;
    }
    
    public String getObjectUUID() {
        return objectUUID;
    }
    
    public void setObjectUUID(String objectUUID) {
        this.objectUUID = objectUUID;
    }
    
    public GameObjectType getObjectType() {
        return objectType;
    }
    
    public void setObjectType(GameObjectType objectType) {
        this.objectType = objectType;
    }
    
    public GameObjectCamp getCamp() {
        return camp;
    }
    
    public void setCamp(GameObjectCamp camp) {
        this.camp = camp;
    }
    
    public long getMasterGuid() {
        return masterGuid;
    }
    
    public void setMasterGuid(long masterGuid) {
        this.masterGuid = masterGuid;
    }
    
    public double getPosX() {
        return posX;
    }
    
    public void setPosX(double posX) {
        this.posX = posX;
    }
    
    public double getPosY() {
        return posY;
    }
    
    public void setPosY(double posY) {
        this.posY = posY;
    }
    
    public double getPosZ() {
        return posZ;
    }
    
    public void setPosZ(double posZ) {
        this.posZ = posZ;
    }
    
    public float getDirectionX() {
        return directionX;
    }
    
    public void setDirectionX(float directionX) {
        this.directionX = directionX;
    }
    
    public float getDirectionY() {
        return directionY;
    }
    
    public void setDirectionY(float directionY) {
        this.directionY = directionY;
    }
    
    public float getDirectionZ() {
        return directionZ;
    }
    
    public void setDirectionZ(float directionZ) {
        this.directionZ = directionZ;
    }
    
    public boolean isActive() {
        return active;
    }
    
    public void setActive(boolean active) {
        this.active = active;
    }
    
    public boolean isDestroyed() {
        return destroyed;
    }
    
    public void setDestroyed(boolean destroyed) {
        this.destroyed = destroyed;
    }
    
    public long getCreateTime() {
        return createTime;
    }
    
    public void setCreateTime(long createTime) {
        this.createTime = createTime;
    }
    
    public long getLastUpdateTime() {
        return lastUpdateTime;
    }
    
    public void setLastUpdateTime(long lastUpdateTime) {
        this.lastUpdateTime = lastUpdateTime;
    }
    
    public boolean isVisible() {
        return visible;
    }
    
    public void setVisible(boolean visible) {
        this.visible = visible;
    }
    
    public long getVisibilityRange() {
        return visibilityRange;
    }
    
    public void setVisibilityRange(long visibilityRange) {
        this.visibilityRange = visibilityRange;
    }

    /**
     * 初始化对象
     */
    public abstract void initialize();

    /**
     * 销毁对象
     */
    public abstract void destroy();

    /**
     * 处理心跳
     * 
     * @param currentTime 当前时间（毫秒）
     * @param deltaTime   时间差（毫秒）
     */
    public abstract void processHeartbeat(long currentTime, long deltaTime);

    /**
     * 获取对象位置
     */
    public Position getPosition() {
        return new Position(posX, posY, posZ);
    }

    /**
     * 设置对象位置
     */
    public void setPosition(Position position) {
        this.posX = position.getX();
        this.posY = position.getY();
        this.posZ = position.getZ();
        this.lastUpdateTime = System.currentTimeMillis();
    }

    /**
     * 获取对象方向
     */
    public Vector3 getDirection() {
        return new Vector3(directionX, directionY, directionZ);
    }

    /**
     * 设置对象方向
     */
    public void setDirection(Vector3 direction) {
        this.directionX = direction.getX();
        this.directionY = direction.getY();
        this.directionZ = direction.getZ();
    }

    /**
     * 获取两个对象之间的距离
     */
    public double getDistance(GameObject other) {
        double dx = this.posX - other.posX;
        double dy = this.posY - other.posY;
        double dz = this.posZ - other.posZ;
        return Math.sqrt(dx * dx + dy * dy + dz * dz);
    }

    /**
     * 获取调试字符串
     */
    public String getDebugString() {
        return String.format("GameObject{id=%d, type=%s, camp=%s, pos=(%f,%f,%f), active=%b, destroyed=%b}", 
                objectId, objectType, camp, posX, posY, posZ, active, destroyed);
    }

    /**
     * 检查对象是否活跃
     */
    public boolean isAlive() {
        return active && !destroyed;
    }

    /**
     * 激活对象
     */
    public void activate() {
        this.active = true;
        this.lastUpdateTime = System.currentTimeMillis();
    }

    /**
     * 停用对象
     */
    public void deactivate() {
        this.active = false;
        this.lastUpdateTime = System.currentTimeMillis();
    }

    @Override
    public String toString() {
        return getDebugString();
    }
}